﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.Globalization;
using Nivdal.AuxCode;
using System.Text;

namespace Nivdal
{
    public partial class CreateTournament : System.Web.UI.Page
    {
        #region Definitions
        public class TournamentDate
        {
            public string RoundText { get; set; }
            public bool IsFirst { get; set; }
            public string SpecialName { get; set; }

            public TournamentDate(bool _IsFirst, int Round)
            {
                IsFirst = _IsFirst;
                RoundText = Resources.Resource.Global_Round + " " + Round.ToString();                
            }
        }
        #endregion

        #region PageEvents
        protected void Page_Load(object sender, EventArgs e)
        {
            Title = Resources.Resource.Default_PageTitle + ", " + Resources.Resource.CreateTournament_PageTitle;
            OnlineUser ou = (OnlineUser)Session["User"];
            GetNivdalData.GetNivdalData GND = new GetNivdalData.GetNivdalData();
            
            if (!HttpContext.Current.User.Identity.IsAuthenticated)
                Response.Redirect("~/Default.aspx");


            if (!ou.IsPremium)
            {
                Response.Redirect("~/AllTournaments.aspx?Message=" + Resources.Resource.Tournament_OnlyPremium);
            }
            


            if (!IsPostBack)
            {
                if ((ou.UserAccessLevel == "5") || (GND.ReadNivdalBoolData("UserId", "Nivdal_CanUserOpenTournament", ou.UserId)))
                    CannotOpenPanel.Visible = false;
                else
                {
                    CannotOpenPanel.Visible = true;
                    Stage1Panel.Visible = false;
                }
                    
 
                TournamentTypeDataSource.SelectParameters.Add("Language", ou.Language);
                TournamentTypeDataSource.SelectParameters.Add("AccessLevel", ou.UserAccessLevel);
                FillNumTeamsDDl(1);
                NationalTeamsPanel.Visible = (ou.UserAccessLevel == "5");
            }

            string script = "<script type=\"text/javascript\" language=\"javascript\">";
            if (PasswordSignupRadioButton.Checked)
            {
                script += "ToggleSignupDiv('1')</script>";
            }
            else
            {
                script += "ToggleSignupDiv('0')</script>";
            }
            Page.ClientScript.RegisterStartupScript(this.GetType(), "PopupScript", script);
        }
        #endregion

        #region Event handlers
        
        protected void TournamentTypeChosen(object sender, EventArgs e)
        {
            FillNumTeamsDDl(int.Parse(TournamentTypeDDL.SelectedValue));
        }
        
        protected void ContinueToStep2(object sender, EventArgs e)
        {
            OnlineUser ou = (OnlineUser)Session["User"];
            bool Validated = true;
            if (PasswordSignupRadioButton.Checked && TournamentPasswordTextBox.Text.Trim().Length == 0)
            {
                Validated = false;
                PleaseChoosePasswordTitleLabel.Visible = true;
            }
            else
                PleaseChoosePasswordTitleLabel.Visible = false;

            if (Validated)
            {
                Stage1Panel.Enabled = false;
                ToStep2Button.Visible = false;
                SetDatesRepeater();
                string IsNationalTeams = (ou.UserAccessLevel == "5") ? NationalTeamsDDL.SelectedValue : "0";
                
                //PrizesSetsDataSource.SelectParameters.Clear();
                //PrizesSetsDataSource.SelectParameters.Add("IsPremium", ou.IsPremium ? "1" : "0");
                //PrizesSetsDataSource.SelectParameters.Add("NumTeams", NumTeamsDDL.SelectedValue);
                //PrizesSetsDataSource.SelectParameters.Add("IsNationalTeams", IsNationalTeams);
                //PrizesSetRepeater.DataSourceID = "PrizesSetsDataSource";
                //PrizesSetsDataSource.DataBind();  


                Stage2Panel.Visible = true;
            }
        }

        protected void FillInTournamentDates(object sender, EventArgs e)
        {
            FillInTournamentDates();
        }

        private void FillInTournamentDates()
        {
            try
            {
                DateTime StartDate = DateTime.Parse((DatesRepeater.Items[0].FindControl("DaysDDL") as DropDownList).SelectedValue);
                StartDate = StartDate.AddHours(int.Parse((DatesRepeater.Items[0].FindControl("HourDDL") as DropDownList).SelectedValue));
                StartDate = StartDate.AddMinutes(int.Parse((DatesRepeater.Items[0].FindControl("MinutesDDL") as DropDownList).SelectedValue));

                for (int i = 1; i < DatesRepeater.Items.Count; i++)
                {
                    StartDate = StartDate.AddDays(7);
                    (DatesRepeater.Items[i].FindControl("DaysDDL") as DropDownList).SelectedValue = DateFormat(StartDate);
                    (DatesRepeater.Items[i].FindControl("HourDDL") as DropDownList).SelectedValue = Format2DigitsNum(StartDate.Hour);
                    (DatesRepeater.Items[i].FindControl("MinutesDDL") as DropDownList).SelectedValue = Format2DigitsNum(StartDate.Minute);
                }
            }
            catch (Exception ex) { ErrorLabel.Text = ex.Message; }
        }

        protected void BackToStage1(object sender, EventArgs e)
        {
            Stage1Panel.Enabled = true;
            ToStep2Button.Visible = true;
            Stage2Panel.Visible = false;
        }

        protected void CreateTournamentButtonClick(object sender, EventArgs e)
        {
            string ValidateInputAnswer = ValidateInput();
            if (ValidateInputAnswer.Length == 0)
            {
                string TournamentId = CreateTournamentEntry();
                if (TournamentId != "0")
                {
                    string Name = TournamentNameTextBox.Text.Trim();
                    AddDates(TournamentId);
                    StartTournament(TournamentId);
                    //Response.Redirect("~/Tournament.aspx?Id=" + TournamentId);
                    Stage2Panel.Visible = false;
                    Stage1Panel.Visible = false;
                    Stage3Panel.Visible = true;

                    DonateTournamentPrizeLink.NavigateUrl = "~/Shop.aspx?TournamentId=" + TournamentId;
                    TournamentHyperlink.NavigateUrl = "~/Tournament.aspx?Id=" + TournamentId;
                    TournamentHyperlink.Text = Name;
                }
            }
            else
            {
                ErrorLabel.Text = ValidateInputAnswer;
            }
            
        }

        #endregion
        

        #region PrivateFunctions

        private void FillNumTeamsDDl(int TournamentType)
        {
            NumTeamsDDL.Items.Clear();

            switch (TournamentType)
            {
                case 1:
                    NumTeamsDDL.Items.Add("4");
                    NumTeamsDDL.Items.Add("6");
                    NumTeamsDDL.Items.Add("8");
                    NumTeamsDDL.Items.Add("10");
                    break;
                case 2:
                    NumTeamsDDL.Items.Add("4");
                    NumTeamsDDL.Items.Add("8");
                    NumTeamsDDL.Items.Add("16");
                    NumTeamsDDL.Items.Add("32");
                    NumTeamsDDL.Items.Add("64");
                    NumTeamsDDL.Items.Add("128");
                    break;
                case 3:
                    NumTeamsDDL.Items.Add("8");
                    NumTeamsDDL.Items.Add("12");
                    NumTeamsDDL.Items.Add("16");
                    NumTeamsDDL.Items.Add("24");
                    NumTeamsDDL.Items.Add("32");
                    break;
                case 4:
                    NumTeamsDDL.Items.Add("0");
                    break;
                case 5:
                    NumTeamsDDL.Items.Add("0");
                    break;
                default:
                    break;
            }
        }
        
        private void SetDatesRepeater()
        {
            List<TournamentDate> TournamentDates = new List<TournamentDate>();

            int NumRounds = NumRoundsForTournament(int.Parse(TournamentTypeDDL.SelectedValue), int.Parse(NumTeamsDDL.SelectedValue));


            for (int i = 0; i < NumRounds; i++)
            {
                TournamentDate NewDate = new TournamentDate(i == 0, i + 1);
                if ((TournamentTypeDDL.SelectedValue != "1") && ((NumRounds - i) <= 3))
                    NewDate.SpecialName = (NumRounds - i).ToString();
                else
                    NewDate.SpecialName = "0";

                TournamentDates.Add(NewDate);
            }


            DatesRepeater.DataSource = TournamentDates;
            DatesRepeater.DataBind();

            List<string> Dates = GetDatesList();

            foreach (RepeaterItem i in DatesRepeater.Items)
            {
                DropDownList d = (i.FindControl("DaysDDL") as DropDownList);
                d.DataSource = Dates;
                d.DataBind();
            }

            FillInTournamentDates();
        }

        private string Format2DigitsNum(int num)
        {
            if (num < 10)
                return "0" + num.ToString();
            return num.ToString();
        }

        private List<string> GetDatesList()
        {
            List<string> List = new List<string>();
            DateTime CurrentDate = DateTime.Now.AddDays(7);

            for (int i = 0; i < 133; i++)
            { 
                List.Add(DateFormat(CurrentDate));
                CurrentDate = CurrentDate.AddDays(1);
            }

            return (List);
        }

        private string DateFormat(DateTime Date)
        {
            return Date.Year.ToString() + "-" + Format2DigitsNum(Date.Month) + "-" + Format2DigitsNum(Date.Day);
        }

        private int NumRoundsForTournament(int Type, int NumTeams)
        {
            int NumRounds = 0;

            switch (Type)
            { 
                case 1:
                    NumRounds = (NumTeams - 1) * 2;
                    break;
                case 2:
                    NumRounds = (int)Math.Log(NumTeams, 2);
                    break;
                case 3:
                    switch (NumTeams)
                    { 
                        case 8:
                            NumRounds = 5;
                            break;
                        case 12:
                            NumRounds = 6;
                            break;
                        case 16:
                            NumRounds = 6;
                            break;
                        case 24:
                            NumRounds = 7;
                            break;
                        case 32:
                            NumRounds = 7;
                            break;
                    }
                    break;
                case 4:
                    // 10 preliminary, 7 for finals.
                    NumRounds = 17;
                    break;
                case 5:
                    NumRounds = 3;
                    break;
            }

            return NumRounds;
        }

        private string ValidateInput()
        {
            string ReturnValue = "";
            // makes sure that all the dates are correct. 
            // some more custom validation may be needed later
            //DateTime CurrentDate = DateTime.Now;
            //DateTime NextDate;

            //foreach (RepeaterItem i in DatesRepeater.Items)
            //{
            //    NextDate = DateTime.Parse((i.FindControl("DaysDDL") as DropDownList).SelectedValue);
            //    NextDate = NextDate.AddHours(int.Parse((i.FindControl("HourDDL") as DropDownList).SelectedValue));
            //    NextDate = NextDate.AddMinutes(int.Parse((i.FindControl("MinutesDDL") as DropDownList).SelectedValue));

            //    if (NextDate < CurrentDate)
            //    {
            //        ReturnValue = Resources.Resource.CreateTournament_IncorrectDateText;
            //        (i.FindControl("DateErrorLabel") as Label).Visible = true;
            //    }
            //    else
            //    {
            //        (i.FindControl("DateErrorLabel") as Label).Visible = false;
            //    }
            //}
            if (!CheckDates())
                ReturnValue = Resources.Resource.CreateTournament_IncorrectDateText;

            return ReturnValue;
        }

        private string CreateTournamentEntry()
        { 
            // creates tournament entry and returns tournament ID
            GetNivdalData.GetNivdalData GND = new GetNivdalData.GetNivdalData();
            OnlineUser ou = (OnlineUser)Session["User"];

            string Name = TournamentNameTextBox.Text.Trim();
            string Type = TournamentTypeDDL.SelectedValue;
            string NumTeams = NumTeamsDDL.SelectedValue;
            string Password = PasswordSignupRadioButton.Checked ? TournamentPasswordTextBox.Text.Trim() : "";
            string IsNationalTeams = (ou.UserAccessLevel == "5") ? NationalTeamsDDL.SelectedValue : "0";
            //string Prizes = "0";

            //foreach (RepeaterItem i in PrizesSetRepeater.Items)
            //{
            //    if ((i.FindControl("SelectedRB") as RadioButton).Checked)
            //    {
            //        Prizes = (i.FindControl("OptionIdHF") as HiddenField).Value;
            //    }
            //}

            
            string TournamentId = GND.ReadNivdalIntData("Name", "Type", "NumOfTeams", "Password", "IsNationalTeams", "DirectorId", 
                "Nivdal_CreateTournament", Name, Type, NumTeams, Password, IsNationalTeams, ou.UserId);
            return TournamentId;

        }

        private void AddDates(string TournamentId)
        { 
            // Adds all the dates to the tournament
            GetNivdalData.GetNivdalData GND = new GetNivdalData.GetNivdalData();
            string Date;
            string SpecialName;
            foreach (RepeaterItem i in DatesRepeater.Items)
            {
                Date = (i.FindControl("DaysDDL") as DropDownList).SelectedValue + " " +
                       (i.FindControl("HourDDL") as DropDownList).SelectedValue + ":" +
                       (i.FindControl("MinutesDDL") as DropDownList).SelectedValue;
                SpecialName = (i.FindControl("SpecialNameHF") as HiddenField).Value;
                GND.ExecNivdalSQL("TournamentId", "Date", "SpecialName", "Nivdal_AddTournamentDate", TournamentId, Date, SpecialName);
            }
        }

        private bool CheckDates()
        {
            List<DateTime> dates = new List<DateTime>();
            DateTime curdate;
                        
            bool ReturnValue = true;
            int year;
            int month;
            int day;
            int hour;
            int minute;
            string[] Daysddlvalue;

            int curIndex;

            try
            {
                foreach (RepeaterItem i in DatesRepeater.Items)
                {
                    Daysddlvalue = (i.FindControl("DaysDDL") as DropDownList).SelectedValue.Split('-');
                    year = int.Parse(Daysddlvalue[0]);
                    month = int.Parse(Daysddlvalue[1]);
                    day = int.Parse(Daysddlvalue[2]);
                    hour =  int.Parse((i.FindControl("HourDDL") as DropDownList).SelectedValue);
                    minute = int.Parse((i.FindControl("MinutesDDL") as DropDownList).SelectedValue);

                    curdate = new DateTime(year, month, day, hour, minute, 0);
                    dates.Add(curdate);
                }
            }
            catch
            {
                ReturnValue = false;
            }

            if (dates.Count <= 1)
                ReturnValue = false;
            else
            {
                curIndex = 0;
                while (curIndex < dates.Count - 1)
                {
                    if ((dates[curIndex + 1] < dates[curIndex].AddHours(12)) ||
                        (dates[curIndex + 1] < DateTime.Now.AddDays(5)))
                        ReturnValue = false;
                    curIndex++;
                }

            }

            return ReturnValue;
        }

        private void StartTournament(string TournamentId)
        { 
            GetNivdalData.GetNivdalData GND = new GetNivdalData.GetNivdalData();
            GND.ExecNivdalSQL("TournamentId", "Nivdal_OpenTournamentForSignup", TournamentId);
        }
        #endregion

        protected override void InitializeCulture()
        {
            OnlineUser ou = (OnlineUser)Session["User"];
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(ou.UICulture);
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ou.Culture);
        }
        
    }

}